import json
import logging
import subprocess
from collections import OrderedDict

from PyQt5.QtCore import QSize
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QLabel, QHBoxLayout, QGroupBox, QLineEdit, QCheckBox, QPushButton,
                             QSizePolicy, QScrollArea)

from config import saved_modules_path
from system import run_command

home_folder = subprocess.run('echo $HOME', shell=True, capture_output=True).stdout.decode().strip()

config_file_path = f'{home_folder}/.config/arm-gia9.conf'

wrong_icon = 'data-warning'
right_icon = 'institution'
icon_size = QSize(16, 16)


class IconLabel(QWidget):
    IconSize = icon_size
    HorizontalSpacing = 2

    def __init__(self, icon_file, text):
        super(QWidget, self).__init__()

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.icon = QLabel()
        self.icon.setPixmap(QIcon.fromTheme(icon_file).pixmap(self.IconSize))

        layout.addWidget(self.icon)
        layout.addSpacing(self.HorizontalSpacing)
        layout.addWidget(QLabel(text))
        layout.addStretch()


class PrepareForExamen(QWidget):
    def __init__(self, zip_archive_filename=None, mainwindow=None):
        super().__init__()

        try:
            with open(saved_modules_path, 'r') as inp:
                self.saved_exams = json.loads(inp.read())
        except Exception as e:
            logging.info(f'Не удалось прочитать сохранённые экзамены из файла. Исключение: {e}')
            self.saved_exams = OrderedDict()

        self.module_filename = zip_archive_filename
        self.module_name = zip_archive_filename.split(".")[0].split('/')[-1].strip()
        if self.module_filename in self.saved_exams.keys():
            self.data = self.saved_exams[self.module_filename]
        else:
            module_dir = f'/tmp/arm-gia9/{self.module_name}'
            self.data = json.loads(open(f'{module_dir}/{self.module_name}.json', 'r').read())
        self.examen_date = self.data['date']
        self.examen_discipline = self.data['discipline']
        self.examen_module = self.data['module']
        self.mainwindow = mainwindow
        self.initUI()

    def check_right_auditory_value(self):
        text = self.auditory_number_lineedit.text().strip()
        if text:
            self.save_auditory_button.setEnabled(True)
        else:
            self.save_auditory_button.setDisabled(True)

    def reserve_checkbox_changed(self):
        if self.reserve_checkbox.isChecked():
            self.auditory_number_lineedit.setDisabled(True)
            self.save_auditory_button.setEnabled(True)
        else:
            self.auditory_number_lineedit.setEnabled(True)
            self.check_right_auditory_value()

    def save_auditory_function(self):
        self.auditory_groupbox_layout.replaceWidget(
            self.auditory_label,
            IconLabel(right_icon, 'Аудитория')
        )
        self.auditory_label = IconLabel(right_icon, 'Аудитория')
        self.data['auditory'] = self.auditory_number_lineedit.text().strip() if not self.reserve_checkbox.isChecked() \
            else "Резерв"
        self.saved_exams[self.module_filename] = self.data
        self.auditory_number_label.setText(f'🚪 {self.data["auditory"]}')
        with open(saved_modules_path, 'w') as out:
            out.write(json.dumps(self.saved_exams, indent=4))

    def initUI(self):
        central_widget = QWidget()
        layout = QVBoxLayout()
        central_widget.setLayout(layout)

        layout.addWidget(QLabel('<h2>Подготовка к экзамену</h2>'))
        info_about_exam_widget = QWidget()
        info_about_exam_widget_layout = QHBoxLayout()
        info_about_exam_widget.setLayout(info_about_exam_widget_layout)
        info_about_exam_widget_layout.addWidget(QLabel(f'📅 {self.examen_date}'))
        info_about_exam_widget_layout.addWidget(QLabel(f'📚 {self.examen_discipline}'))
        info_about_exam_widget_layout.addWidget(QLabel(f'🪟 {self.examen_module}'))
        auditory_number = '0000' if "auditory" not in self.data.keys() else self.data["auditory"]
        self.auditory_number_label = QLabel(f'🚪 {auditory_number}')
        info_about_exam_widget_layout.addWidget(self.auditory_number_label)
        info_about_exam_widget_layout.addStretch()
        info_about_exam_widget.setStyleSheet('QWidget {padding: 5px;}')
        layout.addWidget(info_about_exam_widget)

        auditory_groupbox = QGroupBox()
        self.auditory_groupbox_layout = QVBoxLayout()
        auditory_groupbox.setLayout(self.auditory_groupbox_layout)
        if "auditory" in self.data.keys():
            self.auditory_label = IconLabel(right_icon, 'Аудитория')
        else:
            self.auditory_label = IconLabel(wrong_icon, 'Аудитория')
        self.auditory_groupbox_layout.addWidget(self.auditory_label)
        self.auditory_groupbox_layout.addWidget(QLabel(
            'Укажите сведения об аудитории, в которой будет использоваться модуль '
            '(для резервного модуля номер аудитории не указывается)'))
        input_auditory_number_widget = QWidget()
        input_auditory_number_widget_layout = QHBoxLayout()
        input_auditory_number_widget.setLayout(input_auditory_number_widget_layout)
        self.auditory_number_lineedit = QLineEdit()
        if "auditory" in self.data.keys():
            self.auditory_number_lineedit.setText(self.data["auditory"])
        self.auditory_number_lineedit.textChanged.connect(self.check_right_auditory_value)
        input_auditory_number_widget_layout.addWidget(self.auditory_number_lineedit)
        self.reserve_checkbox = QCheckBox('Резерв')
        self.reserve_checkbox.stateChanged.connect(self.reserve_checkbox_changed)
        input_auditory_number_widget_layout.addWidget(self.reserve_checkbox)
        self.save_auditory_button = QPushButton('Сохранить')
        self.save_auditory_button.clicked.connect(self.save_auditory_function)
        self.save_auditory_button.setDisabled(True)
        input_auditory_number_widget_layout.addWidget(self.save_auditory_button)
        input_auditory_number_widget_layout.addStretch()
        self.auditory_groupbox_layout.addWidget(input_auditory_number_widget)

        layout.addWidget(auditory_groupbox)

        printer_groupbox = QGroupBox()
        printer_groupbox_layout = QVBoxLayout()
        printer_groupbox.setLayout(printer_groupbox_layout)
        current_printer = subprocess.run(f'py-ini-config get {config_file_path} PrinterSettings printer',
                                         shell=True, capture_output=True).stdout.decode().strip()
        self.printer_label = IconLabel(right_icon, 'Принтер') if current_printer else \
            IconLabel(wrong_icon, 'Принтер')
        printer_groupbox_layout.addWidget(self.printer_label)
        self.chosen_printer_label = QLabel(f'Выбранный для печати ЭМ принтер: {current_printer}')
        printer_groupbox_layout.addWidget(self.chosen_printer_label)
        printer_groupbox_layout.addWidget(QLabel('Если требуется изменить принтер, перейдите в настройки печати ЭМ'))
        print_settings_button = QPushButton('Перейти к настройкам печати')
        print_settings_button.clicked.connect(self.mainwindow.open_print_settings)
        printer_groupbox_layout.addWidget(print_settings_button)
        layout.addWidget(printer_groupbox)

        test_print_groupbox = QGroupBox()
        test_print_groupbox_layout = QVBoxLayout()
        test_print_groupbox.setLayout(test_print_groupbox_layout)
        self.test_print_label = IconLabel(wrong_icon, 'Тестовая печать')
        test_print_groupbox_layout.addWidget(self.test_print_label)
        self.necessary_test_print_label = QLabel(f'Выполните печать тестового комплекта ЭМ')
        test_print_groupbox_layout.addWidget(self.necessary_test_print_label)
        test_print_button = QPushButton('Тестовая печать ЭМ')
        test_print_groupbox_layout.addWidget(test_print_button)
        # TODO что здесь должно печататься?
        layout.addWidget(test_print_groupbox)

        scaner_groupbox = QGroupBox()
        scaner_groupbox_layout = QVBoxLayout()
        scaner_groupbox.setLayout(scaner_groupbox_layout)
        current_scaner = subprocess.run(f'py-ini-config get {config_file_path} ScanerSettings scaner',
                                        shell=True, capture_output=True).stdout.decode().strip()
        self.scaner_label = IconLabel(right_icon, 'Сканер') if current_scaner else \
            IconLabel(wrong_icon, 'Сканер')
        scaner_groupbox_layout.addWidget(self.scaner_label)
        self.chosen_scaner_label = QLabel(f'Выбранный сканер: {current_scaner}')
        scaner_groupbox_layout.addWidget(self.chosen_scaner_label)
        scaner_groupbox_layout.addWidget(QLabel('Если требуется изменить сканер, перейдите в настройки сканирования'))
        scan_settings_button = QPushButton('Перейти к настройкам сканирования')
        scan_settings_button.clicked.connect(self.mainwindow.open_scan_settings)
        scaner_groupbox_layout.addWidget(scan_settings_button)
        layout.addWidget(scaner_groupbox)

        test_scan_groupbox = QGroupBox()
        test_scan_groupbox_layout = QVBoxLayout()
        test_scan_groupbox.setLayout(test_scan_groupbox_layout)
        self.test_scan_label = IconLabel(wrong_icon, 'Тестовое сканирование')
        test_scan_groupbox_layout.addWidget(self.test_scan_label)
        self.necessary_test_scan_label = QLabel(f'Выполните сканирование тестового комплекта ЭМ')
        test_scan_groupbox_layout.addWidget(self.necessary_test_scan_label)
        test_scan_button = QPushButton('Тестовое сканирование ЭМ')
        test_scan_groupbox_layout.addWidget(test_scan_button)
        layout.addWidget(test_scan_groupbox)

        audio_groupbox = QGroupBox()
        audio_groupbox_layout = QVBoxLayout()
        audio_groupbox.setLayout(audio_groupbox_layout)
        current_audio_driver = subprocess.run(f'py-ini-config get {config_file_path} AudioSettings audiodriver',
                                              shell=True, capture_output=True).stdout.decode().strip()
        self.audio_label = IconLabel(right_icon, 'Драйвер аудио') if current_audio_driver else \
            IconLabel(wrong_icon, 'Драйвер аудио')
        audio_groupbox_layout.addWidget(self.audio_label)
        self.chosen_audio_label = QLabel(f'Выбранный аудиодрайвер: {current_audio_driver}')
        audio_groupbox_layout.addWidget(self.chosen_audio_label)
        audio_groupbox_layout.addWidget(QLabel('Если требуется изменить аудиодрайвер, перейдите в настройки звука'))
        audio_settings_button = QPushButton('Перейти к настройкам звука')
        audio_settings_button.clicked.connect(lambda: self.mainwindow.open_audio_settings())
        audio_groupbox_layout.addWidget(audio_settings_button)
        layout.addWidget(audio_groupbox)

        token_groupbox = QGroupBox()
        token_groupbox_layout = QVBoxLayout()
        token_groupbox.setLayout(token_groupbox_layout)
        self.token_label = IconLabel(wrong_icon, 'Проверка токена')
        token_groupbox_layout.addWidget(self.token_label)
        token_check_button = QPushButton('Проверить токен')
        token_check_button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        token_groupbox_layout.addWidget(token_check_button)
        layout.addWidget(token_groupbox)

        protocol_groupbox = QGroupBox()
        protocol_groupbox_layout = QVBoxLayout()
        protocol_groupbox.setLayout(protocol_groupbox_layout)
        self.protocol_label = IconLabel(wrong_icon, 'Протокол')
        protocol_groupbox_layout.addWidget(self.protocol_label)
        protocol_check_button = QPushButton('Печать протокола')
        protocol_check_button.setDisabled(True)
        protocol_groupbox_layout.addWidget(protocol_check_button)
        layout.addWidget(protocol_groupbox)

        readiness_act_groupbox = QGroupBox()
        readiness_act_groupbox_layout = QVBoxLayout()
        readiness_act_groupbox.setLayout(readiness_act_groupbox_layout)
        self.readiness_act_label = IconLabel(wrong_icon, 'Акт готовности')
        readiness_act_groupbox_layout.addWidget(self.readiness_act_label)
        readiness_act_check_button = QPushButton('Сохранить акт')
        readiness_act_check_button.setDisabled(True)
        readiness_act_groupbox_layout.addWidget(readiness_act_check_button)
        layout.addWidget(readiness_act_groupbox)

        layout.addStretch()

        scroll_area = QScrollArea()
        scroll_area.setWidget(central_widget)

        prepare_for_examen_layout = QVBoxLayout()
        prepare_for_examen_layout.addWidget(scroll_area)
        self.setLayout(prepare_for_examen_layout)
